module RubyBuzz
  #
  # Handles a single button on the Buzz controllers.
  #
  # Identified by event code, all between 704 and 723.
  # Also identifiable by pad and name.
  #
  # Possible names:
  #
  # * buzz
  # * yellow
  # * green
  # * orange
  # * blue
  #
  # Initialized in RubyBuzz::Pad.init_mappings
  #
  # Each button holds an array of events, each of which is a
  # Proc to be called without arguments. These are called when
  # the button is pushed.
  #
  class Button

    @@buttons = []

    # events will be an array of lambdas
    attr_accessor :name, :code, :events

    #
    # Initialize a button
    #
    # called in RubyBuzz::Pad.init_mappings
    #
    # Arguments:
    #
    # * code - Integer, the evnt code generated by this button (704-723)
    # * name - Symbol, the name of the button, for referncing via the Pad object
    # * pad - RubyBuzz::Pad, the object this button belongs to
    #
    def initialize(code, name, pad)
      @code = code
      @name = name
      @pad = pad
      @events = []
      @@buttons << self
    end

    #
    # Find a button by its event code. Used by trigger_key
    # to find a button when one is pushed.
    #
    # Arguments:
    #
    # * code - Integer, event code to retrieve button by.
    #
    def self.find(code)
      @@buttons.detect { |b| b.code == code }
    end

    #
    # Add a process to be triggered when this button is pressed.
    #
    # Arguments:
    #
    # * proc - Proc, ruby method to be called, without arguments on button press.
    #
    def add_event(proc)
      @events << proc
    end

    #
    # Trigger every proc in the @events array.
    #
    def trigger_events
      @events.each do |event|
        event.call
      end
    end

    #
    # Find a button and run all it's events.
    #
    # Used by RubyBuzz::Device when button is pushed.
    #
    # Arguments:
    #
    # * code - Integer, event code to retrieve button by.
    #
    def self.trigger_key(code)
      btn = self.find(code)
      btn.trigger_events
    end

  end
end